from grammar.context_free_grammar import *
from grammar.utils import *
import os, sys

sys.path.append(os.getcwd())

PYTHON_CMD = 'python3'
TMP_OUTPUT = './out.txt'


class Checker:
    @staticmethod
    def handle_lines(lines):
        for index, item in enumerate(lines):
            lines[index] = item.strip()

    @staticmethod
    def go(a: str, b: str):
        with open(a, 'r') as f1:
            with open(b, 'r') as f2:
                lines1 = f1.readlines()
                lines2 = f2.readlines()
                Checker.handle_lines(lines1)
                Checker.handle_lines(lines2)

                n = len(lines1)
                m = len(lines2)

                if n != m:
                    return False, 'different number of lines'
                for index, line in enumerate(lines1):
                    if lines1[index] != lines2[index]:
                        return False, 'different content on line {}, content_a = {}, content_b = {}'.format(index, lines1[index], lines2[index])

        return True, "AC"


class TestCase:
    def __init__(self, input_file, std_output, testpy, checker=Checker()):
        self.input = input_file
        self.std = std_output
        self.py = testpy
        self.checker = checker
        pass

    

    @staticmethod
    def relative_path_to_module(path: str):
        res = path.replace('./', '')
        res = res.replace('.py', '')
        res = res.replace('/', '.')
        return res

    @staticmethod
    def run(py: str, input_file: str, output_file: str):
        if not os.path.exists(py) or not os.path.exists(input_file):
            raise Exception('python file not found for {} {}'.format(py, input_file))
        os.system(f'{PYTHON_CMD} -m {TestCase.relative_path_to_module(py)} < {input_file} > {output_file}')

    @staticmethod
    def auto_gen_testdata(std_py: str, input_file: str, test_case_name = None, save_loc='./testdata'):
        '''
        auto gen testcase input and output from a std .py file
        '''

        if not os.path.exists(std_py) or not os.path.exists(input_file):
            raise Exception('file not found for {}, {}'.format(std_py, input_file))

        if test_case_name is None:
            test_case_name = os.path.basename(std_py).split('.')[-2]

        t_std_file = os.path.join(save_loc, test_case_name + '.ans')
        t_run_py = os.path.join(save_loc, test_case_name + '.py')
        t_input_file = os.path.join(save_loc, test_case_name + '.in')

        os.system(f'cp {input_file} {t_input_file}')
        os.system(f'cp {std_py} {t_run_py}')
        TestCase.run(t_run_py, t_input_file, t_std_file)

        return TestCase(t_input_file, t_std_file, t_run_py)

    def go(self):
        TestCase.run(self.py, self.input, TMP_OUTPUT);
        verdict, msg = self.checker.go(TMP_OUTPUT, self.std)
        return verdict, msg
    pass



def main():
    cfg = regular_grammar_input('./in.txt')
    print(cfg)
    pass

if __name__ == '__main__':
    main()
